package com.example.blog.module.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.blog.module.entity.ArticleLike;
import com.example.blog.module.entity.Follow;
import com.example.blog.module.mapper.ArticleLikeMapper;
import com.example.blog.module.service.ArticleLikeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.blog.module.utils.BaseContent;
import com.example.blog.module.utils.RedisKeyUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zjx
 * @since 2023-04-09
 */
@Service
@RequiredArgsConstructor
public class ArticleLikeServiceImpl extends ServiceImpl<ArticleLikeMapper, ArticleLike> implements ArticleLikeService {

    private final RedisTemplate redisTemplate;

    private final ArticleLikeMapper articleLikeMapper;

    /**
     * 点赞
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void like(String entityType, Long entityId){
        Long userid = BaseContent.get().getId();
        String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType,entityId);
        Boolean isExits = redisTemplate.hasKey(entityLikeKey);
        Boolean isLike;
        if (isExits){
            isLike = redisTemplate.opsForSet().isMember(entityLikeKey,userid);
        }
        else {
            LambdaQueryWrapper<ArticleLike> wrapper =new LambdaQueryWrapper<>();
            wrapper.eq(ArticleLike::getArticleId,entityId);

            List<Long> userIds = articleLikeMapper.selectList(wrapper).stream().map(ArticleLike::getUserId).collect(Collectors.toList());
            isLike = userIds.stream().anyMatch(userid::equals);
        }
        if (isLike){
            LambdaQueryWrapper<ArticleLike> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ArticleLike::getUserId,userid);
            wrapper.eq(ArticleLike::getArticleId,entityId);
            articleLikeMapper.delete(wrapper);
            redisTemplate.opsForSet().remove(entityLikeKey,userid);
        }else {
            ArticleLike articleLike = new ArticleLike();
            articleLike.setArticleId(entityId);
            articleLike.setUserId(userid);
            articleLike.setCreateTime(new Date());
            articleLikeMapper.insert(articleLike);
            redisTemplate.opsForSet().add(entityLikeKey,userid);
        }
    }

    /**
     * 查询某实体点赞数量
     */
    @Override
    public Long findEntityLikeCount(String entityType, Long entityId){
        String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType,entityId);
        Boolean isExits = redisTemplate.hasKey(entityLikeKey);
        if (!isExits){
            LambdaQueryWrapper<ArticleLike> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ArticleLike::getArticleId, entityId);
            List<Long> followIds = articleLikeMapper.selectList(wrapper).stream().map(ArticleLike::getUserId).collect(Collectors.toList());
            for (Long id:followIds) {
                redisTemplate.opsForSet().add(entityLikeKey,id);
            }
        }
        return redisTemplate.opsForSet().size(entityLikeKey);
    }

    /**
     * 查询某人对某实体的点赞状态
     */
    @Override
    public Integer likeStatus(String entityType, Long entityId) {
        Long userid = BaseContent.get().getId();
        String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);
        Boolean isExits = redisTemplate.hasKey(entityLikeKey);
        if (!isExits){
            LambdaQueryWrapper<ArticleLike> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ArticleLike::getArticleId, entityId);
            List<Long> followIds = articleLikeMapper.selectList(wrapper).stream().map(ArticleLike::getUserId).collect(Collectors.toList());
            for (Long id:followIds) {
                redisTemplate.opsForSet().add(entityLikeKey,id);
            }
        }
        return redisTemplate.opsForSet().isMember(entityLikeKey,userid) ? 1 : 0;
    }
}
